﻿using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Folding;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace LunarSF.SHomeWorkshop.LunarMarkdownEditor
{
    /// <summary>
    /// 此类用以定义CSS编辑器的折叠区。
    /// </summary>
    class CssFoldingStrategy : AbstractFoldingStrategy
    {
        private ICSharpCode.AvalonEdit.TextEditor edit;
        /// <summary>
        /// 要应用折叠功能的编辑器。
        /// </summary>
        public ICSharpCode.AvalonEdit.TextEditor Edit { get { return this.edit; } }

        /// <summary>
        /// [构造方法]创建一个新的折叠区。
        /// </summary>
        public CssFoldingStrategy(ICSharpCode.AvalonEdit.TextEditor edit)
        {
            this.edit = edit;
        }

        /// <summary>
        /// 为特定文档创建 NewFolding 对象集。
        /// </summary>
        public override IEnumerable<NewFolding> CreateNewFoldings(TextDocument document, out int firstErrorOffset)
        {
            firstErrorOffset = -1;
            return CreateNewFoldings(document);
        }

        /// <summary>
        /// 为 CSS 文档创建 NewFolding 对象集。
        /// </summary>
        public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document)
        {
            List<NewFolding> newFoldings = new List<NewFolding>();

            #region 添加自定义折叠块
            string startRegion = @"^.*\{";
            string endRegion = @"^ {0,}\}";

            Stack<LineInfo> regionStartLinesStack = new Stack<LineInfo>();

            for (int i = 1; i <= edit.LineCount; i++)
            {
                var line = edit.Document.GetLineByNumber(i);

                string lineText = edit.Document.GetText(line.Offset, line.Length);
                Regex regexStart = new Regex(startRegion);
                var matchStart = regexStart.Match(lineText);

                if (matchStart != null && matchStart.Success)
                {
                    regionStartLinesStack.Push(new LunarMarkdownEditor.LineInfo()
                    {
                        Line = line,
                        LineText = lineText,
                        HeaderText = lineText.Substring(0, matchStart.Length - 1).Trim(new char[] { ' ', '　', '\t', }),
                    });
                }
                else
                {
                    Regex regexEnd = new Regex(endRegion);
                    var matchEnd = regexEnd.Match(lineText);

                    if (matchEnd != null && matchEnd.Success)// && preRegionLine != null)
                    {
                        if (regionStartLinesStack.Count > 0)
                        {
                            var preRegionLine = regionStartLinesStack.Pop();
                            newFoldings.Add(new NewFolding(preRegionLine.Line.Offset, line.EndOffset)
                            {
                                Name = (preRegionLine.HeaderText == null ? $"{{{lineText.Substring(matchEnd.Length)}}}" : $"{{{preRegionLine.HeaderText}}}"),
                                IsSpecial = true,
                            });
                        }
                    }
                }
            }
            #endregion

            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return newFoldings;
        }
    }
}
